<?php

require __DIR__.DIRECTORY_SEPARATOR.'StoCodeTableBuilder.php';

class StoFirstCodeTableBuilder extends StoCodeTableBuilder
{
    /**
     *
     */
    const TRANS_CENTER_CODE_STRUCT = [
        'branch_code' =>[
          'branch_code' => '',  //转运中心编码
          'branch_name' => '',  //转运中心名
          'codes' => [
            [
              'pack_name' => 'code',  //打包名 => 一段码
            ],
          ],
        ]
    ];

    /**
     *
     */
    const TRANS_CENTER_SIMPLE_CODE_STRUCT = [
        'branch_code' =>[
          'codes' => [
            [
              'pack_name' => 'code',  //打包名 获取一段码
            ],
          ],
        ]
    ];

    /**
     *
     */
    const FILE_INFO_MAP = [
      0 => '省份',
      1 => '所属转运中心',
      2 => '建包名称',
      3 => '包号',
      4 => '转运中心代码',
      5 => '集包属性',
    ];

    /**
     * code field name
     */
    const COLUMN_CENTER_CODE = 'trans_center_code';
    const COLUMN_CENTER_NAME = 'trans_center_name';
    const COLUMN_PROVINCE_NAME = 'province';
    const COLUMN_CODES_KEY = 'codes';
    const COLUMN_PACK_NAME = 'pack_name';
    const COLUMN_CODE_NAME = 'code';
    const COLUMN_PACK_ATTR = 'pack_attr';


    /**
     * code map
     */
    const CODE_MAP = [
        self::COLUMN_CENTER_CODE => 4,
        self::COLUMN_CENTER_NAME => 1,
        self::COLUMN_PACK_NAME => 2,
        self::COLUMN_CODE_NAME => 3,
        self::COLUMN_PROVINCE_NAME => 0,
        self::COLUMN_PACK_ATTR => 5, //包属性
    ];
    /**
     *
     */
    const CODE_STRING_MAP = [
        self::COLUMN_CENTER_CODE => '转运中心代码',
        self::COLUMN_CENTER_NAME => '所属转运中心',
        self::COLUMN_PACK_NAME => '建包名称',
        self::COLUMN_CODE_NAME => '包号',
        self::COLUMN_PROVINCE_NAME => '省份',
        self::COLUMN_PACK_ATTR => '集包属性',
    ];
    /**
     * handler map
     */
    const SPECIAL_COLUMN_MAP = [
        self::COLUMN_PROVINCE_NAME => 'getValidProvinceName',
        self::COLUMN_CENTER_NAME => 'getValidCenterName',
    ];

    const FILE_STORE_NAME = '1st_codes.php';

    /**
     * @var array
     */
    protected $codeBaseArray;

    /**
     * @var string
     */
    protected $lastValidCenterName;

    /**
     * @var string
     */
    protected $lastValidProvinceName;

    protected function build()
    {
        $this->buildCodeBaseArray();
    }

    /**
     * @param array $data
     * @return array
     */
    private function formatInfo(array $data) : array
    {
        $structureData = [];
        foreach (static::CODE_MAP as $column => $index) {
            if(array_key_exists($column, static::SPECIAL_COLUMN_MAP)){
                $structureData[$column] = trim(call_user_func([$this, static::SPECIAL_COLUMN_MAP[$column]], $data[$index]));
            }else{
                $structureData[$column] = trim($data[$index]);
            }
        }
        return $this->lastFormattedRowInfo = $structureData;
    }

    /**
     * @return array
     */
    private function buildCodeBaseArray() : array
    {
        $data = [];
        $structureData = [];
        $lastCenterName = '';
        $codesCount = [];
        foreach ($this->codeArray as $item) {
            $centerInfo = $this->formatInfo($item);
            $centerCode = $centerInfo[static::COLUMN_CENTER_CODE];
            $data[$centerCode][] = $centerInfo;
            if(!empty($centerInfo[static::COLUMN_CENTER_NAME]) && $lastCenterName !== $centerInfo[static::COLUMN_CENTER_NAME]){
                $lastCenterName = $centerInfo[static::COLUMN_CENTER_NAME];
                // $structureData[$centerCode]['1st_code_count_'] = 1;
                $structureData[$centerCode] = $this->filterData($centerInfo);
            }
            empty($structureData[$centerCode]['1st_code_count']) and $structureData[$centerCode]['1st_code_count'] = 1 or $structureData[$centerCode]['1st_code_count']++;
            $structureData[$centerCode][static::COLUMN_CODES_KEY][$centerInfo[static::COLUMN_PACK_NAME]] = $centerInfo[static::COLUMN_CODE_NAME];
        }
        // foreach ($structureData as $key => $val) {
        //     $structureData[$key]['1st_code_count'] = count($val[static::COLUMN_CODES_KEY]);
        // }
        return $this->codeBaseArray = $structureData;
    }

    /**
     * @param array $data
     * @return array
     */
    private function filterData(array $data) : array
    {
        return array_intersect_key($data, array_flip([
           static::COLUMN_PROVINCE_NAME,
           static::COLUMN_CENTER_NAME,
           static::COLUMN_CENTER_CODE,
        ]));
    }

    /**
     *
     */
    protected function init()
    {
        $this->toArray();
        static::$requiredFields = array_keys(static::CODE_STRING_MAP);
    }

    /**
     * @return array
     */
    protected function toFile(): array
    {
        $result = [];
        if ($this->codeBaseArray && is_array($this->codeBaseArray)) {
            $result[] = file_put_contents(static::FILE_STORE_NAME, static::FILE_CONTENT_PREFIX . var_export($this->codeBaseArray, true).';');
        }
        return $result;
    }

    /**
     * @param string $str
     * @return string
     */
    private function getValidProvinceName(string $str) : string
    {
        return !$str ? $this->lastValidProvinceName : $this->lastValidProvinceName = $str;
    }

    /**
     * @param string $name
     * @return string
     */
    private function getValidCenterName(string $name) : string
    {
        return !$name ? $this->lastValidCenterName : $this->lastValidCenterName = $name;
    }
}


$filePath = __DIR__.DIRECTORY_SEPARATOR.'20170116_1st_code.csv';
(new StoFirstCodeTableBuilder($filePath))->run();
